/*
 * Operation.h
 *
 *  Created on: Jul 24, 2011
 *      Author: or frenkel
 */

#ifndef OPERATION_H_
#define OPERATION_H_

#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <iostream>
#include <cassert>
#include "../DataStructures/Molecule.h"
#include "../computations/PermutationsGroup.h"

#define APPROX_RUN_PER_SEC 8e4
#define MAXDOUBLE  100000000.0


typedef enum {
	CN,
	SN,
	CS,
	CI,
	CH
} OperationType;

typedef FILE* FileP;

/*
 * This class represents an interface for a single operation such as C2 etc.
 */
class Operation{

protected:
	OperationType _type; //TODO maybe doesn't need this if the operation type will have a class
	int _opOrder;
	std::string _opName;
	FileP _inFile;
	std::string _inFileName;
	FileP _outFile;
	Molecule* _mol;
	//Flags
	bool _findPerm, _usePerm, _timeOnly;

	/**
	 * Read a molecule from a file file
	 *
	 * @param filename The file name to read from
	 * @param format   The file format in Open Babel terms (if NULL is given, attempt to get
	 * format from the suffix)
	 * @param babelBond Should the convertor let openbabel choose bonding
	 * @return The OBMol read from the file
	 */
	void readAndCreateMolecule ();


	/*
	 * checks if the molecule's group permutations exceed GROUPSIZE_FACTOR_PER_MINUTE * MINUTES
	 */
	virtual double numPermutations();

	/*
	 * reutnrs n!
	 */
	double factorial(int n);

public:

	/*ctor*/
	Operation(int argc, char *argv[]);

	/*copy-ctor*/
	Operation(Operation& other): _type(other._type), _opOrder(other._opOrder),
			_opName(other._opName),_inFile(other._inFile), _outFile(other._outFile) {}

	Molecule* getMolecule(){ return _mol; }

	/*
	 * give approximation for the remaining time for the calculations.
	 * NOTICE: not available for all the operations!!
	 */
	void estimateRemainingTime();

	/*
	 * The operation itself!! most important function!
	 * TODO: need to overridden in other operation
	 */
	void operate();

	~Operation(){
		delete _mol;
	}

private:


};

//============================ C_Operation class ===================================

/*
 * This class inherit from Operation and it implements the C operation.
 * =======For now it's only for C2 operation===========
 */
class C_Operation : public Operation{

public:
	/*ctor*/
	C_Operation(int argc, char *argv[]);

	/* d-tor */
	~C_Operation(){}
};

//============================ S_Operation class =====================================

/*
 * This class inherit from Operation and it implements the S operation.
 */
class S_Operation : public Operation{

protected:
	/* overridden
	 *
	 * checks if the molecule's group permutations exceed GROUPSIZE_FACTOR_PER_MINUTE * MINUTES
	 */
	double numPermutations();

public:
	/*ctor*/
	S_Operation(int argc, char *argv[]);

	/* d-tor */
	~S_Operation(){}
};





#endif /* OPERATION_H_ */
